From f0010ba27fa5f5f18d051cd427c8a361f3c07cd1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 23 Dec 2005 16:42:46 +0100 Subject: [PATCH] Modify CR0 access emulation -- return physical CR0 (except for TS) and allow only the same physical flags to be written back to CR0 by a guest. Add write-to-CR4 emulation, but check that the write does not modify any CR4 flags. Signed-off-by: Keir Fraser --- xen/arch/x86/traps.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 8e1ca7f579..40959e6758 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -885,7 +885,8 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) switch ( modrm_reg ) { case 0: /* Read CR0 */ - *reg = v->arch.guest_context.ctrlreg[0]; + *reg = (read_cr0() & ~X86_CR0_TS) | + v->arch.guest_context.ctrlreg[0]; break; case 2: /* Read CR2 */ @@ -927,6 +928,11 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) switch ( modrm_reg ) { case 0: /* Write CR0 */ + if ( (*reg ^ read_cr0()) & ~X86_CR0_TS ) + { + DPRINTK("Attempt to change unmodifiable CR0 flags.\n"); + goto fail; + } (void)do_fpu_taskswitch(!!(*reg & X86_CR0_TS)); break; @@ -941,6 +947,14 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) UNLOCK_BIGLOCK(v->domain); break; + case 4: + if ( *reg != (read_cr4() & ~(X86_CR4_PGE|X86_CR4_PSE)) ) + { + DPRINTK("Attempt to change CR4 flags.\n"); + goto fail; + } + break; + default: goto fail; } -- 2.30.2